JVM 内存区域(一)

JVM内存区域(一)

1. 运行时内存区域分类

JVM运行时内存区域主要包含:

  • 程序计数器
  • 方法区
    其中属于线程私有的是程序计数器;属于共享的是方法区

    2. 运行时内存区域含义

  • 程序计数器

    程序计数器是一块较小的内存空间,他可以当做当前线程执行的字节码的行号指示器。

    • java虚拟机栈

      和大多数程序语言一样,每个java方法在jvm解释执行时都会创建一个栈帧存储局部变量操作数栈动态链接方法出口信息。 ​
      每一个方法的调用到执行返回,都对应一个栈帧在虚拟机栈中入栈和出栈的过程。
      局部变量表存放了编译时期确定的各种基本数据类型(boolean、byte、char、short、int、float、long、double)、对象引用类型(reference类型)。其中long和double会占据两个局部变量槽(slot),其余的占据一个slot

    • 本地方法栈

      本地方法调用形成的栈,类似于java虚拟机栈;

  • 所有的对象实例以及数组都要在堆上分配。

  • 方法区

    和堆内存一样,是各个线程共享的内存区域,用于存储已经被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据。

    • 运行时常量池(runtime constant pool)

      运行时常量池是方法区的一部分。Class文件里面除了包含类版本、字段、方法、接口等描述信息外,还有一项就是常量表(符号表 constant pool table),用于存放编译时期(源码到字节码)产生的各种字面量和符号引用,例如 public int a = 2中的a,这部分内容在类加载后会进入方法区的运行时常量池
      运行时常量池相对于class文件的常量表的区别:

      • 常量表必须符合class文件严格的规范才会被虚拟机加载;而运行时常量池则是由不同的虚拟机厂商自由发挥实现的;
      • 运行时常量池具有动态性,常量并非只有在编译时期产生,也就是并非置入class文件中常量表的内容才能进入方法区中的运行时常量池,运行期间也可能有新的常量进入池中,这种特性就是常用的string.inter()方法。
  • 直接内存(Direct Memory)

    直接内存不是虚拟机运行时数据的一部分,java语言提供一些接口能够使用native函数直接分配堆外内存(通常意义下虚拟机管理的内存以外的内存),参见NIO